package com.hp.bon.sgw.core.processor;

import java.util.LinkedHashMap;
import static com.hp.bon.sgw.Constants.LOG;
import java.util.Map;

import com.hp.bon.sgw.Constants;
import com.hp.bon.sgw.bean.CapabilityCtrlBean;
import com.hp.bon.sgw.core.CallParam;
import com.hp.bon.sgw.start.SpringContext;
import com.hp.bon.sgw.util.dcc.DccAvpHelper;
import com.hp.ocs.diameter.message.AVP;
import com.hp.ocs.diameter.message.AVP_Grouped;
import com.hp.ocs.diameter.message.AVP_UTF8String;
import com.hp.ocs.diameter.message.AVP_Unsigned32;
import com.hp.ocs.diameter.message.Message;
import com.hp.ocs.diameter.message.MessageDictionary;

/**
 * 完成业务能力优先级变更控制消息的实现
 * 
 * @author wuzhih
 * 
 */
public class SLAMsgProcessor extends Processor
{
  public int process(CallParam callParam)
  {
    Message request = (Message)callParam.getRequest();
    AVP avp = null;
    AVP_Grouped serviceContextAVP = null;

		Message answer = new Message();
		answer.prepareResponse(request);
		MessageDictionary md = request.getDictionary();
		md.prepareResponseAVP(answer);
		try {
			avp = request.find(Constants.DIAMETER_AVP_SERVICE_INFOMATION, Constants.DIAMETER_VENDOR_3GPP);
			AVP_Grouped serviceInfsAVP = new AVP_Grouped(avp);
			avp = serviceInfsAVP.find(Constants.DIAMETER_AVP_NET_CTRL_INFOMATION, Constants.DIAMETER_VENDOR_CT);
			AVP_Grouped netCtrlInfsAVP = new AVP_Grouped(avp);
			avp = netCtrlInfsAVP.find(Constants.DIAMETER_AVP_NE_INFOMATION, Constants.DIAMETER_VENDOR_CT);
			// 查找所有的ServiceContextInfomation AVP
			AVP[] allServiceContextInfs = netCtrlInfsAVP.queryAVPs();
			Map<String, CapabilityCtrlBean> capsPriority = new LinkedHashMap<String, CapabilityCtrlBean>();
			boolean parseFailed = false;
			CapabilityCtrlBean ccbean = null;
			for (AVP theAVP : allServiceContextInfs) {
				if (theAVP.code() == Constants.DIAMETER_AVP_SERVICE_CONTEXT_INFOMATION) {
					serviceContextAVP = new AVP_Grouped(theAVP);
					AVP capAVP = serviceContextAVP.find(80051, Constants.DIAMETER_VENDOR_CT);
					if (capAVP == null) {
						LOG.warn("bad capablitiy ccr message ,Capabilities avp missing ");
						parseFailed = true;
						break;
					}
					String cap = new AVP_UTF8String(capAVP).queryValue();
					AVP prorityAVP = serviceContextAVP.find(80037, Constants.DIAMETER_VENDOR_CT);
					if (prorityAVP == null) {
						LOG.warn("bad capablitiy ccr message ,priority avp missing ");
						parseFailed = true;
						break;
					}
					int priority = new AVP_Unsigned32(prorityAVP).queryValue();

					ccbean = new CapabilityCtrlBean();
					ccbean.setCapability(cap);
					ccbean.setPriority(priority);

					AVP timeoutWarningAVP = serviceContextAVP.find(80044, Constants.DIAMETER_VENDOR_CT);
					if (timeoutWarningAVP == null) {
						LOG.warn("bad capablitiy ccr message ,TimeOutWarning avp missing ");
					} else {
						ccbean.setTimeoutWarning(new AVP_Unsigned32(timeoutWarningAVP).queryValue());
					}

					AVP timeoutDropMsgAVP = serviceContextAVP.find(80045, Constants.DIAMETER_VENDOR_CT);
					if (timeoutDropMsgAVP == null) {
						LOG.warn("bad capablitiy ccr message ,DiscardTime avp missing ");
					} else {
						ccbean.setTimeoutDropMsg(new AVP_Unsigned32(timeoutDropMsgAVP).queryValue());
					}
					capsPriority.put(cap, ccbean);
				}
			}

			if (parseFailed) {
				answer.add(new AVP_Unsigned32(Constants.DIAMETER_AVP_RESULT_CODE, Constants.DIAMETER_RESULT_MISSING_AVP));
			} else {
				// 更新消息优先级
				updateCapabilitiesPriority(capsPriority);
				answer.add(new AVP_Unsigned32(Constants.DIAMETER_AVP_RESULT_CODE, Constants.DIAMETER_RESULT_SUCCESS));
				answer.add(DccAvpHelper.genDefaultServiceResultAVP(Constants.DIAMETER_SERVICE_RESULT_SUCCESS));

			}

		} catch (Exception e) {
			answer.add(new AVP_Unsigned32(Constants.DIAMETER_AVP_RESULT_CODE, Constants.DIAMETER_RESULT_UNABLE_TO_COMPLY));
		}

		callParam.setResponse(answer);
		callParam.getAsynHandler().onCallResult(callParam);
		return 0;
	}

  public int endProcess(CallParam callParam)
  {
    return 0;
  }

  private void updateCapabilitiesPriority(Map<String, CapabilityCtrlBean> capsPriority) {
    if (capsPriority.isEmpty()) {
      return;
    }
    StringBuilder sb = new StringBuilder().append(" update capability priority :\r\n");
    Map capabilityCtrlMap = SpringContext.getInstance().getConfigService().getCapabilityCtrlMap();

    String sql = null;
    CapabilityCtrlBean ccbean = null;
    for (Map.Entry entry : capsPriority.entrySet()) {
      String cap = (String)entry.getKey();
      ccbean = (CapabilityCtrlBean)entry.getValue();
      CapabilityCtrlBean exisitBean = (CapabilityCtrlBean)capabilityCtrlMap.get(cap);
      if (exisitBean == null) {// 新的能力
        capabilityCtrlMap.put(cap, ccbean);
        sql = "insert into  T_CAPABILITY_INFO (capability,capabilityDesc,priority,priorityDate,timeoutWarning,timeoutDropMsg,ifKeyStat) values ('" + cap + "','" + cap + "'," + ccbean.getPriority() + ",sysdate" + "," + ccbean.getTimeoutWarning() + "," + ccbean.getTimeoutDropMsg() + 
          ",false) ";
      } else {
        sql = "update T_CAPABILITY_INFO  set priority = " + ccbean.getPriority() + ", priorityDate = sysdate ,timeoutWarning = " + ccbean.getTimeoutWarning() + " ,timeoutDropMsg = " + ccbean.getTimeoutDropMsg() + " where capability = '" + cap + "'";
      }
      Constants.LOG.info("update sql " + sql);
      capabilityCtrlMap.put(cap, ccbean);
      SpringContext.getInstance().getDataStoreService().addHSQL(sql, false);
      sb.append(ccbean.toString()).append("\r\n");
    }
    Constants.LOG.info(sb.toString());
  }
}
